package com.qqtech.qquan.user.service;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.qqtech.core.common.enums.YesNoEnum;
import com.qqtech.core.common.exception.BizzException;
import com.qqtech.core.common.util.StringUtil;
import com.qqtech.core.common.util.TimeUtil;
import com.qqtech.core.frame.dao.BaseDao;
import com.qqtech.core.frame.model.Result;
import com.qqtech.core.frame.service.BaseServiceImpl;
import com.qqtech.qquan.sms.helper.SmsCfg;
import com.qqtech.qquan.sms.service.SmsBaseService;
import com.qqtech.qquan.user.cache.UserSysParamCache;
import com.qqtech.qquan.user.dao.UserVerifycodeDao;
import com.qqtech.qquan.user.enums.UserConst;
import com.qqtech.qquan.user.enums.UserIdentityTypeDictEnum;
import com.qqtech.qquan.user.enums.UserVerifycodeTypeDictEnum;
import com.qqtech.qquan.user.model.UserVerifycode;

@Service
public class UserVerifycodeServiceImpl extends BaseServiceImpl<UserVerifycode>implements UserVerifycodeService {
	public static final Logger log = LoggerFactory.getLogger(UserVerifycodeServiceImpl.class);
	@Resource
	private SmsBaseService smsBaseService;
	@Resource
	private UserVerifycodeDao userVerifycodeDao;

	@Override
	protected BaseDao<UserVerifycode> getBaseDao() {
		return userVerifycodeDao;
	}

	@Resource
	private UserIdentityService userIdentityService;
	@Resource
	private UserSysParamCache userSysParamCache;

	@Override
	public Result checkValidCode(String identity, String verifycode, UserVerifycodeTypeDictEnum userVerifycodeType) {
		Result result = new Result();
		if (StringUtil.isBlank(identity) || StringUtil.isBlank(verifycode)) {
			result.addErr("账号或验证码参数为空");
		}
		if (userVerifycodeType == null) {
			userVerifycodeType = UserVerifycodeTypeDictEnum.REG_LOGIN;
		}
		UserVerifycode userVerifycode = new UserVerifycode();
		userVerifycode.setChannelId(identity);
		userVerifycode.setCode(verifycode);
		userVerifycode.setType(userVerifycodeType.getCode());
		userVerifycode = userVerifycodeDao.getOne(userVerifycode);
		if (userVerifycode == null) {
			result.addErr("验证码有误");
		} else {
			Timestamp t = userVerifycode.getExpireAt();
			if (YesNoEnum.NO.getCode() != userVerifycode.getIsVerify() || t == null || t.before(TimeUtil.now())) {
				result.addErr("验证码已失效");
			}
		}
		if (!result.checkForm()) {
			return result;
		}
		result.put("verifycodeId", userVerifycode.getId());
		return result;
	}

	@Override
	public Result addVerifycode(UserIdentityTypeDictEnum userVerifycodeChannel, String channelId,
			UserVerifycodeTypeDictEnum userVerifycodeType) throws BizzException {
		Result result = new Result();
		if (userVerifycodeChannel == null || userVerifycodeType == null || StringUtil.isBlank(channelId)) {
			// throw new BizzException("申请发送验证码的参数有误");
			result.addErr("申请发送验证码的参数有误");
		}
		if (UserIdentityTypeDictEnum.PHONE.equals(userVerifycodeChannel)) {
			if (!StringUtil.isPhone(channelId)) {
				// throw new BizzException("手机号码不正确");
				result.addErr("手机号码不正确");
			}
		}
		String code = productVerifycodeByType(userVerifycodeType);
		Map<String, String> params = new HashMap<String, String>();
		params.put("code", code);
		if (result.checkForm()) {
			result = smsBaseService.send(channelId, SmsCfg.getInstance().getIntValue("sms.template.user.verify", 1001),
					params);
			if (result.checkForm()) {
				UserVerifycode userVerifycode = new UserVerifycode();
				userVerifycode.setIsVerify(YesNoEnum.NO.getCode());
				userVerifycode.setChannel(userVerifycodeChannel.getCode());
				userVerifycode.setChannelId(channelId);
				userVerifycode.setCode(code);
				userVerifycode.setType(userVerifycodeType.getCode());
				int mins = getExpireMins(userVerifycodeType);
				userVerifycode.setExpireAt(TimeUtil.addMins(TimeUtil.now(), mins));
				int id = userVerifycodeDao.insert(userVerifycode);
				result.put("userVerifycodeId", id);
				result.put("userVerifycodeCode", userVerifycode.getCode());
				result.put("userVerifycodeTips", "验证码已发送，请在" + mins + "分钟内使用，逾期无效");
				result.setMsg("验证码已发送，请在" + mins + "分钟内使用，逾期无效");
			}
		}
		return result;
	}

	/**
	 * 根据业务类型生成随机验证码内容
	 * 
	 * @param userVerifycodeType
	 * @return
	 */
	private String productVerifycodeByType(UserVerifycodeTypeDictEnum userVerifycodeType) {
		if (userVerifycodeType.equals(UserVerifycodeTypeDictEnum.REG_LOGIN)) {
			return StringUtil.getRandomNum(6);
		} else if (userVerifycodeType.equals(UserVerifycodeTypeDictEnum.CHANGEIDENTITY)) {
			return StringUtil.getRandomNum(6);
		}
		return StringUtil.getRandomNum(4);
	}

	/**
	 * 根据要验证的业务类型获取对应的失效时间分钟数
	 * 
	 * @param userVerifycodeType
	 * @return
	 */
	private Integer getExpireMins(UserVerifycodeTypeDictEnum userVerifycodeType) {
		if (userVerifycodeType.equals(UserVerifycodeTypeDictEnum.REG_LOGIN)) {
			return userSysParamCache.getInt(UserConst.PARAMKEY_USER_VERIFYCODE_REGISTER_EXPIRE, 5);
		} else if (userVerifycodeType.equals(UserVerifycodeTypeDictEnum.REG_LOGIN)) {
			return userSysParamCache.getInt(UserConst.PARAMKEY_USER_VERIFYCODE_LOGIN_EXPIRE, 5);
		} else if (userVerifycodeType.equals(UserVerifycodeTypeDictEnum.CHANGEIDENTITY)) {
			return userSysParamCache.getInt(UserConst.PARAMKEY_USER_VERIFYCODE_CHANGECHANNEL_EXPIRE, 5);
		}
		return userSysParamCache.getInt(UserConst.PARAMKEY_USER_VERIFYCODE_DEFAULT_EXPIRE, 5);
	}
}